package org.nightrunner.d3.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
import org.nightrunner.d3.model.IPaginationInfo;
import org.nightrunner.d3.model.PaginationModel;
import org.springframework.dao.DataAccessException;

/**
 * Top-level interface to common hibernate, all hibernate operation of parent
 * interface is <b>IGenericDao</b>
 * 
 * @author Night Runner
 * @param <T>
 * @param <ID>
 */
public interface IGenericDao<T, ID extends Serializable> {

	/**
	 * hibernate entity class loading by PK id
	 * 
	 * @param id
	 *            table PK id
	 * @return hibernate entity
	 * @throws DataAccessException
	 */
	public SessionFactory getSessionFactory() throws DataAccessException;

	/**
	 * hibernate entity class loading by PK id
	 * 
	 * @param id
	 *            table PK id
	 * @return hibernate entity
	 * @throws DataAccessException
	 */
	public T load(ID id) throws DataAccessException;

	/**
	 * find hibernate entity by pk id
	 * 
	 * @param id
	 *            id table PK id
	 * @return hibernate entity
	 * @throws DataAccessException
	 */
	public T get(ID id) throws DataAccessException;

	/**
	 * hibernate entity class exists
	 * 
	 * @param t
	 *            hibernate entity
	 * @return boolean,when return true entity exists,false not exists ;
	 * @throws DataAccessException
	 */
	public boolean contains(T t) throws DataAccessException;

	/**
	 * through a variety of locking mechanism to refresh the hibernate entity
	 * class
	 * 
	 * @param t
	 *            hibernate entity
	 * @param lockMode
	 *            hibernate locking mechanism
	 * @throws DataAccessException
	 */
	public void refresh(T t, LockMode lockMode) throws DataAccessException;

	/**
	 * refresh hibernate entity
	 * 
	 * @param t
	 *            hibernate entity
	 * @throws DataAccessException
	 */
	public void refresh(T t) throws DataAccessException;

	/**
	 * save hibernate entity
	 * 
	 * @param t
	 *            hibernate entity
	 * @return Serializable result
	 * @throws DataAccessException
	 */
	public Serializable save(T t) throws DataAccessException;

	/**
	 * method saveOrUpdate can save or update hibernate entity class to database
	 * 
	 * @param t
	 * @throws DataAccessException
	 */
	public void saveOrUpdate(T t) throws DataAccessException;

	/**
	 * save or update a collection of hibernate entity class
	 * 
	 * @param entities
	 *            hibernate entity collection
	 * @throws DataAccessException
	 */
	public void saveOrUpdateAll(Collection<T> entities)
			throws DataAccessException;

	/**
	 * through a variety of locking mechanism to update the hibernate entity
	 * class
	 * 
	 * @param t
	 *            hibernate entity
	 * @param lockMode
	 *            hibernate locking mechanism
	 * @throws DataAccessException
	 */
	public void update(T t, LockMode lockMode) throws DataAccessException;

	/**
	 * update a hibernate entity class
	 * 
	 * @param t
	 *            hibernate entity
	 * @throws DataAccessException
	 */
	public void update(T t) throws DataAccessException;

	/**
	 * through a variety of locking mechanism to delete the hibernate entity
	 * class
	 * 
	 * @param t
	 *            hibernate entity
	 * @param lockMode
	 *            hibernate locking mechanism
	 * @throws DataAccessException
	 */
	public void delete(T t, LockMode lockMode) throws DataAccessException;

	/**
	 * delete a hibernate entity class
	 * 
	 * @param t
	 *            hibernate entity
	 * @throws DataAccessException
	 */
	public void delete(T t) throws DataAccessException;

	/**
	 * update a collection of hibernate entity class
	 * 
	 * @param entities
	 *            collection of hibernate entity
	 * @throws DataAccessException
	 */
	public void deleteAll(Collection<T> entities) throws DataAccessException;

	/**
	 * through hql to find list of hibernate entity class
	 * 
	 * @param queryString
	 *            hql
	 * @param value
	 * @return list of value
	 * @throws DataAccessException
	 */
	public List<T> find(String queryString, Object value)
			throws DataAccessException;

	/**
	 * through hql to find list of hibernate entity class
	 * 
	 * @param queryString
	 * @param values
	 * @return
	 * @throws DataAccessException
	 */
	public List<T> find(String queryString, Object[] values)
			throws DataAccessException;

	/**
	 * through hql to find list of hibernate entity class
	 * 
	 * @param queryString
	 * @return
	 * @throws DataAccessException
	 */
	public List<T> find(String queryString) throws DataAccessException;

	/**
	 * find a list of <T>
	 * 
	 * @return
	 * @throws DataAccessException
	 */
	public List<T> list() throws DataAccessException;

	/**
	 * through hbm.xml attribute "name" to query hibernate entity
	 * 
	 * @param queryName
	 *            hbm.xml attribute name
	 * @return List of <T>
	 * @throws DataAccessException
	 */
	public List<T> findByNamedQuery(String queryName)
			throws DataAccessException;

	/**
	 * through hbm.xml attribute "name" to query hibernate entity
	 * 
	 * @param queryName
	 *            hbm.xml attribute name
	 * @return List of <T>
	 * @throws DataAccessException
	 */
	public List<T> findByNamedQuery(String queryName, Object value)
			throws DataAccessException;

	/**
	 * through hbm.xml attribute "name" to query hibernate entity
	 * 
	 * @param queryName
	 *            hbm.xml attribute name
	 * @return List of <T>
	 * @throws DataAccessException
	 */
	public List<T> findByNamedQuery(String queryName, Object[] values)
			throws DataAccessException;

	/**
	 * find data by ids
	 * 
	 * @param ids
	 * @return list of dto
	 * @throws DataAccessException
	 */
	public List<T> findByIds(String[] ids) throws DataAccessException;

	/**
	 * find data by ids
	 * 
	 * @param ids
	 * @return list of dto
	 * @throws DataAccessException
	 */
	public List<T> findByIds(List<String> ids) throws DataAccessException;

	/**
	 * find data by paginationModel
	 * 
	 * @param paginationModel
	 *            page model
	 * @return PaginationModel
	 * @throws DataAccessException
	 */
	public PaginationModel<List<T>> find(
			PaginationModel<List<T>> paginationModel)
			throws DataAccessException;

	/**
	 * find data by paginationInfo
	 * 
	 * @param paginationModel
	 *            page model
	 * @return PaginationModel
	 * @throws DataAccessException
	 */
	public PaginationModel<List<T>> find(IPaginationInfo paginationInfo)
			throws DataAccessException;

	/**
	 * update a hibernate entity class
	 * 
	 * @param t
	 *            hibernate entity
	 * @throws DataAccessException
	 */
	public void merge(T t) throws DataAccessException;

	PaginationModel<List<T>> find(IPaginationInfo paginationInfo, String where);

	PaginationModel<List<T>> find(PaginationModel<List<T>> paginationModel,
			String where);
}